package cn.zto.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import cn.zto.job.SimpleJob;
import cn.zto.vo.PageTrigger;

@Repository("jobService")
public class JobService {

	@Autowired
	private Scheduler scheduler;
	
	public List<JobDetail> getJobs(){
		try {
			GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
			Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
			
			List<JobDetail> jobDetails = new ArrayList<JobDetail>();
			
			for (JobKey key : jobKeys) {
				jobDetails.add(scheduler.getJobDetail(key));
			}
			return jobDetails;
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
		 
		 return null;
	}
	
	//获取所有的触发器
	public List<PageTrigger> getTriggersInfo(){
		try {
			GroupMatcher<TriggerKey> matcher = GroupMatcher.anyTriggerGroup();
			Set<TriggerKey> Keys = scheduler.getTriggerKeys(matcher);
			List<PageTrigger> triggers = new ArrayList<PageTrigger>();
			
			for (TriggerKey key : Keys) {
				Trigger trigger = scheduler.getTrigger(key);
				PageTrigger pageTrigger = new PageTrigger();
				pageTrigger.setName(trigger.getJobKey().getName());
				pageTrigger.setGroup(trigger.getJobKey().getGroup());
				pageTrigger.setStatus(scheduler.getTriggerState(key)+"");
				if (trigger instanceof SimpleTrigger) {
					SimpleTrigger simple = (SimpleTrigger) trigger;
					pageTrigger.setExpression("重复次数:"+ (simple.getRepeatCount() == -1 ? 
							"无限" : simple.getRepeatCount()) +",重复间隔:"+(simple.getRepeatInterval()/1000L));
					pageTrigger.setDesc(simple.getDescription());
				}
				if (trigger instanceof CronTrigger) {
					CronTrigger cron = (CronTrigger) trigger;
					pageTrigger.setExpression(cron.getCronExpression());
					pageTrigger.setDesc(cron.getDescription());
				}
				triggers.add(pageTrigger);
			}
			return triggers;
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public void add(String jobName, String jobGroup){
		try {
			// TriggerKey : name + group
			TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
			JobKey jobKey = new JobKey(jobName, jobGroup);
			
			// TriggerKey valid if_exists
			if (checkExists(jobName, jobGroup)) {
				return;
			}
			
			// CronTrigger : TriggerKey + cronExpression	// withMisfireHandlingInstructionDoNothing 忽略掉调度终止过程中忽略的调度
			CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/8 * * * * ?").withMisfireHandlingInstructionDoNothing();
			CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
			
			// JobDetail : jobClass
			Class<? extends Job> jobClass_ = SimpleJob.class;   // Class.forName(jobInfo.getJobClass());
			JobDetail jobDetail = JobBuilder.newJob(jobClass_).withIdentity(jobKey).build();
			
			// schedule : jobDetail + cronTrigger
			Date date = scheduler.scheduleJob(jobDetail, cronTrigger);
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
	}
	
	public void add2(String name, String group){

		Class<? extends Job> jobClass_ = SimpleJob.class; 
		
		JobDetail job = JobBuilder.newJob(jobClass_).withIdentity("jobB", "group_job_b").build();
		SimpleScheduleBuilder simpleScheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
				.withIntervalInSeconds(5).repeatForever();
		Trigger trigger = TriggerBuilder.newTrigger().withIdentity("triggerB", "group_tri_b")
				.withSchedule(CronScheduleBuilder.cronSchedule("*/10 * * * * ?"))
				.build();
		try {
			scheduler.scheduleJob(job, trigger);
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
	}
	
	
	//暂停任务
	public void stopJob(String name, String group){
		JobKey key = new JobKey(name, group);
		try {
			scheduler.pauseJob(key);
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
	}
	
	//恢复任务
	public void restartJob(String name, String group){
		JobKey key = new JobKey(name,group);
		try {
			scheduler.resumeJob(key);
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
	}
	
	
	//立马执行一次任务
	public void startNowJob(String jobName, String jobGroup){
		try {
			// TriggerKey : name + group
	    	JobKey jobKey = new JobKey(jobName, jobGroup);
	        
	        boolean result = false;
			if (checkExists(jobName, jobGroup)) {
			    scheduler.triggerJob(jobKey);
			    result = true;
			    System.out.println(">>>>>>>>>>> runJob success, jobKey:" + jobKey);
			} else {
				System.out.println(">>>>>>>>>>> runJob fail, jobKey:" + jobKey);
			}
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
	}
	
	//删除任务
	public void delJob(String name, String group){
		JobKey key = new JobKey(name,group);
		try {
			scheduler.deleteJob(key);
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
	}
	
	//修改触发器时间
	public void modifyTrigger(String name,String group,String cron){
		try {
			TriggerKey key = TriggerKey.triggerKey(name, group);
			Trigger trigger = scheduler.getTrigger(key);
			
			CronTrigger newTrigger = (CronTrigger) TriggerBuilder.newTrigger()
					.withIdentity(key)
					.withSchedule(CronScheduleBuilder.cronSchedule(cron))
					.build();
			scheduler.rescheduleJob(key, newTrigger);
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
		
	}
	
	//暂停调度器
	public void stopScheduler(){
		 try {
			if (!scheduler.isInStandbyMode()) {
				scheduler.standby();
			}
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
	}


    /**
     * check if exists
     *
     * @param jobName
     * @param jobGroup
     * @return
     * @throws SchedulerException
     */
	public boolean checkExists(String jobName, String jobGroup) throws SchedulerException{
		TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
		return scheduler.checkExists(triggerKey);
	}

}
